/**
 * @file	adc.c
 * @author	chipsea
 * @brief	Contains all functions support for adc driver
 * @version	0.1
 * @date	2020-11-30
 * @copyright Copyright (c) 2020, CHIPSEA Co., Ltd.
 * @note
 */
#ifndef __ADC__H__
#define __ADC__H__

#ifdef __cplusplus
extern "C" {
#endif

#include "types.h"
#include "gpio.h"

#define    MAX_ADC_SAMPLE_SIZE     32
#define    ADC_CH_BASE             (0x40050400UL)


#define    CLEAR_ADC_INT(n)     AP_ADC->INT_CLR |= BIT(n)


#define    IS_CLAER_ADC_INT_VOICE (AP_ADC->INT_CLR & BIT(8))
#define    IS_CLAER_ADC_INT(n)    (AP_ADC->INT_CLR & BIT(n))
    
#define    GET_IRQ_STATUS         (AP_ADCC->INT_FLAG & 0x3ff)

#define    ENABLE_ADC             (AP_PCRM->ANA_CTL |= BIT(3))
#define    DISABLE_ADC            (AP_PCRM->ANA_CTL &= ~BIT(3))
    
#define    ADC_CLOCK_ENABLE       (AP_PCRM->CLKHF_CTL1 |= BIT(13))
#define    ADC_CLOCK_DISABLE       (AP_PCRM->CLKHF_CTL1 &= ~BIT(13))

#define    ADC_CH0_POINTER				(AP_ADCC->INTP0 & 0x0000003f)
#define    ADC_CH1_POINTER				(AP_ADCC->INTP0 & (0x0000003f << 6))>>6
#define    ADC_CH2_POINTER				(AP_ADCC->INTP0 & (0x0000003f << 12))>>12
#define    ADC_CH3_POINTER				(AP_ADCC->INTP0 & (0x0000003f << 18))>>18
#define    ADC_CH4_POINTER				(AP_ADCC->INTP1 & 0x0000003f)
#define    ADC_CH5_POINTER				(AP_ADCC->INTP1 & (0x0000003f << 6))>>6
#define    ADC_CH6_POINTER				(AP_ADCC->INTP1 & (0x0000003f << 12))>>12
#define    ADC_CH7_POINTER				(AP_ADCC->INTP1 & (0x0000003f << 18))>>18

#define SPIF_RSVD_AREA_1                 (0x1008)
#define pSPIF_RSVD1_ADC_CALIBRATE       ((volatile uint32_t*)(SPIF_BASE_ADDR + SPIF_RSVD_AREA_1))
#define SPIF_RSVD1_ADC_CALIBRATE        (SPIF_BASE_ADDR + SPIF_RSVD_AREA_1)
	

typedef enum {
	ADC_CH0DIFF = 1,/*p18(positive),p25(negative),only works in diff*/
    ADC_CH0 = 2,ADC_CH1N_P11 = 2,MIN_ADC_CH = 2,
    ADC_CH1 = 3,ADC_CH1P_P23 = 3,/*P23 and P11*/
    ADC_CH2 = 4,ADC_CH2N_P24 = 4,
    ADC_CH3 = 5,ADC_CH2P_P14 = 5,/*P14 and P24*/
    ADC_CH4 = 6,ADC_CH3N_P15 = 6,
    ADC_CH9 = 7,ADC_CH3P_P20 = 7,MAX_ADC_CH = 7,/*P20 and P15*/
    ADC_CH_VOICE = 8,
    ADC_CH_NUM =9,
}AdcChannel_t;

#define ADC_BIT(ch) (1<<ch)

enum{
  HAL_ADC_EVT_DATA = 1,
  HAL_ADC_EVT_FAIL = 0xff
};

typedef enum {
	HAL_ADC_CLOCK_80K = 0,
	HAL_ADC_CLOCK_160K = 1,
	HAL_ADC_CLOCK_320K = 2,
}AdcClockSel_t;

typedef struct _adc_Cfg_t{
  uint8_t channel_flag;
  bool  is_continue_mode; 
  uint8_t  is_high_resolution; 
}AdcCfg_t;


typedef struct _adc_Evt_t{
  int       type;
  AdcChannel_t  ch;
  uint16_t* data;
  uint8_t   size; //word size
}AdcEvt_t;

typedef void (*adc_Hdl_t)(AdcEvt_t* pev);



extern GpioPin_t s_pinmap[ADC_CH_NUM];


void HalAdcInit(void);

int HalAdcChannelConfig(AdcCfg_t cfg, adc_Hdl_t evt_handler);

int HalAdcClockConfig(AdcClockSel_t clk);

int HalAdcStart(void);

int HalAdcStop(void);

void __attribute__((weak)) HalAdcIRQHandler(void);

int32_t HalAdcValueCal(AdcChannel_t ch,uint16_t* buf, uint32_t size, uint8_t high_resol);

#ifdef __cplusplus
}
#endif

#endif
